package net.jgrm.order.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

@Configuration
@RefreshScope
public class GracefulThreadPoolConfig {

    private static final Logger logger = LoggerFactory.getLogger(GracefulThreadPoolConfig.class);

    // 使用静态变量跨实例共享线程池引用
    private static final AtomicReference<ThreadPoolTaskExecutor> sharedCurrentExecutor = new AtomicReference<>();

    // 任务迁移队列
    private static final BlockingQueue<Runnable> migrationQueue = new LinkedBlockingQueue<>();

    // 正在迁移标志
    private static final AtomicBoolean migrating = new AtomicBoolean(false);

    @Value("${thread.pool.core-pool-size:5}")
    private int corePoolSize;

    @Value("${thread.pool.max-pool-size:10}")
    private int maxPoolSize;

    @Value("${thread.pool.queue-capacity:100}")
    private int queueCapacity;

    @Bean("gracefulTaskExecutor")
    @RefreshScope
    public ThreadPoolTaskExecutor gracefulTaskExecutor() {
        // 使用共享引用而不是实例变量
        ThreadPoolTaskExecutor current = sharedCurrentExecutor.get();

        if (current != null) {
            // 开始迁移流程
            logger.info("检测到现有线程池，开始处理线程池迁移流程");
            startMigration();
        }

        ThreadPoolTaskExecutor newExecutor = createNewExecutor();
        sharedCurrentExecutor.set(newExecutor);
        logger.info("创建新的线程池实例: corePoolSize={}, maxPoolSize={}, queueCapacity={}",
                corePoolSize, maxPoolSize, queueCapacity);
        return newExecutor;
    }

    @PostConstruct
    public void init() {
        logger.info("初始化线程池配置: corePoolSize={}, maxPoolSize={}, queueCapacity={}",
                corePoolSize, maxPoolSize, queueCapacity);
    }

    private ThreadPoolTaskExecutor createNewExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("graceful-pool-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(120);
        executor.initialize();

        // 处理之前存储的迁移任务
        processPendingMigrationTasks(executor);

        return executor;
    }

    private void startMigration() {
        if (migrating.compareAndSet(false, true)) {
            try {
                logger.info("开始线程池迁移流程");
                ThreadPoolTaskExecutor oldExecutor = sharedCurrentExecutor.get();
                if (oldExecutor != null) {
                    // 1. 停止接收新任务
                    oldExecutor.getThreadPoolExecutor().shutdown();
                    // 2. 等待一段时间让正在执行的任务完成
                    awaitGracefulCompletion(oldExecutor);
                    // 3. 迁移剩余任务（如果有未完成的任务）
                    migrateRemainingTasks(oldExecutor);
                }
                logger.info("线程池迁移完成");
            } finally {
                migrating.set(false);
            }
        }
    }

    private void awaitGracefulCompletion(ThreadPoolTaskExecutor oldExecutor) {
        try {
            // 先尝试优雅关闭，给正在执行的任务一些时间完成
            if (!oldExecutor.getThreadPoolExecutor().awaitTermination(30, TimeUnit.SECONDS)) {
                logger.warn("优雅关闭超时，将强制关闭并迁移剩余任务");
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            logger.warn("等待任务完成时被中断");
        }
    }

    private void migrateRemainingTasks(ThreadPoolTaskExecutor oldExecutor) {
        try {
            // 强制关闭并获取所有未执行的任务
            List<Runnable> remainingTasks = oldExecutor.getThreadPoolExecutor().shutdownNow();

            if (remainingTasks != null && !remainingTasks.isEmpty()) {
                logger.info("迁移 {} 个剩余任务到新线程池", remainingTasks.size());

                int migratedCount = 0;
                int failedCount = 0;

                for (Runnable task : remainingTasks) {
                    try {
                        ThreadPoolTaskExecutor current = sharedCurrentExecutor.get();
                        if (current != null) {
                            current.execute(task);
                            migratedCount++;
                        } else {
                            migrationQueue.offer(task);
                        }
                    } catch (Exception e) {
                        failedCount++;
                        handleMigrationFailure(task, e);
                    }
                }

                logger.info("剩余任务迁移完成: 成功 {} 个, 失败 {} 个", migratedCount, failedCount);
            }
        } catch (Exception e) {
            logger.error("迁移剩余任务时发生异常", e);
            handleMigrationException(e);
        }
    }

    private void processPendingMigrationTasks(ThreadPoolTaskExecutor executor) {
        if (!migrationQueue.isEmpty()) {
            logger.info("处理 {} 个待迁移的任务", migrationQueue.size());

            int processed = 0;
            int failed = 0;

            while (!migrationQueue.isEmpty()) {
                try {
                    Runnable task = migrationQueue.poll(1, TimeUnit.SECONDS);
                    if (task != null) {
                        executor.execute(task);
                        processed++;
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                } catch (Exception e) {
                    failed++;
                    logger.error("处理待迁移任务失败", e);
                }
            }

            logger.info("待迁移任务处理完成: 成功处理 {} 个, 失败 {} 个", processed, failed);
        }
    }

    private void handleMigrationFailure(Runnable task, Exception exception) {
        try {
            // 将失败的任务存储到持久化队列中
            if (!migrationQueue.offer(task, 5, TimeUnit.SECONDS)) {
                logger.error("无法将失败的任务添加到迁移队列，任务可能丢失");
            }

            // 记录失败日志，可用于后续人工处理或自动重试
            logger.error("任务迁移失败，已存储到备份队列: {}", task.getClass().getName(), exception);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            logger.error("处理迁移失败时被中断");
        }
    }

    private void handleMigrationException(Exception exception) {
        // 记录详细的错误信息
        logger.error("线程池任务迁移异常，可能造成任务丢失", exception);

        // 可以发送告警通知
        sendAlert("线程池迁移异常", "任务可能丢失，请检查系统状态");
    }

    private void sendAlert(String title, String message) {
        // 实现告警逻辑，如发送邮件、短信或调用监控系统API
        logger.warn("发送告警: {} - {}", title, message);
    }
}
